{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "aae2a396-5ff6-4d4b-a9b9-74dceb10e6ca",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.cluster import KMeans\n",
    "\n",
    "# 生成虚拟数据\n",
    "np.random.seed(0)\n",
    "X = np.vstack([np.random.normal(loc=0, scale=1, size=(100, 2)),\n",
    "               np.random.normal(loc=5, scale=1, size=(100, 2)),\n",
    "               np.random.normal(loc=10, scale=1, size=(100, 2))])\n",
    "\n",
    "# 使用k-Means聚类\n",
    "kmeans = KMeans(n_clusters=3)\n",
    "kmeans.fit(X)\n",
    "y_kmeans = kmeans.predict(X)\n",
    "\n",
    "# 绘制聚类结果\n",
    "plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, cmap='viridis')\n",
    "plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=300, c='red', marker='X')\n",
    "plt.title('k-Means Clustering on Virtual Data')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f22544f4-6446-4732-a02e-6ce69ec587da",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算不同k值下的SSE\n",
    "sse = []\n",
    "k_range = range(1, 11)\n",
    "for k in k_range:\n",
    "    kmeans = KMeans(n_clusters=k)\n",
    "    kmeans.fit(X)\n",
    "    sse.append(kmeans.inertia_)\n",
    "\n",
    "# 绘制肘部法图\n",
    "plt.plot(k_range, sse, marker='o')\n",
    "plt.title('Elbow Method for Optimal k')\n",
    "plt.xlabel('Number of clusters (k)')\n",
    "plt.ylabel('SSE')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b469f76d-055c-452d-8d42-8a5db7581ec5",
   "metadata": {},
   "outputs": [],
   "source": [
    "import cv2\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# Load the car number image\n",
    "image_carno = cv2.imread('D:\\BaiduNetdiskDownload\\car_num.jpg')\n",
    "\n",
    "# Display the image\n",
    "fig, ax = plt.subplots(figsize=(7,7))\n",
    "ax.imshow(cv2.cvtColor(image_carno, cv2.COLOR_BGR2RGB))\n",
    "ax.axis('off')  # Remove axes\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dec4500d-fa6b-4805-9a66-a2c6ab867e5e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Change image_carno into grey image\n",
    "image_carno_grey = cv2.cvtColor(image_carno, cv2.COLOR_BGR2GRAY)\n",
    "\n",
    "# Display the image\n",
    "fig, ax = plt.subplots(figsize=(7,7))\n",
    "img = ax.imshow(image_carno_grey, cmap='gray')\n",
    "plt.axis('off')  # Hide axes\n",
    "# plt.savefig('carno_grey.png', dpi=300) # Make figure clearer\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4f7661b4-a5df-425e-aaf9-4824b22c023c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "# Reshape image_carno_grey into a 1-D vector\n",
    "x = image_carno_grey.reshape(-1)\n",
    "\n",
    "# Using k-Means to separate background and foreground by pixels\n",
    "k = 2\n",
    "\n",
    "# Initialize cluster centers\n",
    "cluster_centers = np.random.rand(k) * 255\n",
    "start_centers = cluster_centers.copy()\n",
    "\n",
    "# Initialize distance array\n",
    "distance = np.zeros((len(x), k))\n",
    "\n",
    "# Intercation\n",
    "start_time = time.time()\n",
    "max_iter = 1000\n",
    "for iter_id in range(max_iter):\n",
    "    # Calculate distance between points to each center\n",
    "    for i in range(k):\n",
    "        distance[:,i] = np.abs(x - cluster_centers[i])\n",
    "\n",
    "    # Assign to closest centroid\n",
    "    cluster_idx = np.argmin(distance, axis=1)\n",
    "\n",
    "    # Update cluster centers\n",
    "    cluster_centers_prior = cluster_centers.copy()\n",
    "    for i in range(k):\n",
    "        cluster_centers[i] = np.mean(x[cluster_idx == i])\n",
    "\n",
    "    # Check if cluster_centers are stable enough to stop training\n",
    "    print(f'Iteration {iter_id}: Updated centers {cluster_centers}, Prior centers {cluster_centers_prior}')\n",
    "    if np.sum(np.abs(cluster_centers-cluster_centers_prior)) == 0:\n",
    "        break\n",
    "\n",
    "    cluster_centers_prior = cluster_centers\n",
    "\n",
    "end_time = time.time()\n",
    "print(f'Stop after iteration {iter_id}, time consumption is {end_time-start_time}')\n",
    "\n",
    "# Using cluster_idx to general segmentation mask\n",
    "carno_mask_pixel = cluster_idx.reshape(image_carno_grey.shape)\n",
    "\n",
    "# Display the mask\n",
    "fig, ax = plt.subplots(figsize=(7,7))\n",
    "img = ax.imshow(carno_mask_pixel, cmap='gray')\n",
    "ax.set_title(f'Init Centers: {start_centers}, Iteration: {iter_id}')\n",
    "plt.axis('off')  # Hide axes\n",
    "# plt.savefig('carno_mask_pixel_2.png', dpi=300) # Make figure clearer\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "75d26b81-857d-42b2-bc5e-c6360dc5ee80",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.cluster import KMeans\n",
    "import cv2\n",
    "\n",
    "# 1. 读取图像\n",
    "image = cv2.imread('D:\\BaiduNetdiskDownload\\car_num.jpg')  # 这里换成你自己选择的图像路径\n",
    "image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)  # 将图像从BGR转换为RGB格式\n",
    "\n",
    "# 2. 获取图像的像素数据并进行预处理\n",
    "height, width, channels = image.shape\n",
    "pixels = image.reshape(-1, 3)  # 将图像数据转换为一个二维数组，包含所有像素的RGB值\n",
    "\n",
    "# 3. 对不同k值进行k-Means聚类，并可视化结果\n",
    "k_values = [2, 3, 5, 10]  # 选择不同的k值进行聚类\n",
    "fig, axes = plt.subplots(1, len(k_values), figsize=(15, 5))\n",
    "\n",
    "for i, k in enumerate(k_values):\n",
    "    # 使用k-Means聚类\n",
    "    kmeans = KMeans(n_clusters=k, random_state=42)\n",
    "    kmeans.fit(pixels)\n",
    "    \n",
    "    # 将聚类结果映射回原图像尺寸\n",
    "    clustered_img = kmeans.cluster_centers_[kmeans.labels_].reshape(height, width, 3).astype(np.uint8)\n",
    "    \n",
    "    # 显示结果\n",
    "    axes[i].imshow(clustered_img)\n",
    "    axes[i].set_title(f'k = {k}')\n",
    "    axes[i].axis('off')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4ad63af2-3a15-453f-9641-d51a76ea648e",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
